﻿using UnityEngine;
using ZiZi.Graphics.Sampling.Hammersley;
using System.Collections.Generic;
using System;

namespace ZiZi.Graphics.OfflineBaker
{

    ///////////////////////////////////////// Baking Quality /////////////////////////////////////////
    [Serializable]
    public enum BakeQuality
    {
        Sketch = 128,         // 128 samples
        Mockup = 512,         // 512 samples
        Great = 1024,          // 1024 samples
        Production = 2048,     // 2048 samples
        Ultra = 4096           // 4096 samples
    };

    /// <summary>
    ///  Baking delegate function.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="_objToBake"></param>
    /// <param name="bakingObjList"></param>
    /// <param name="extraObjList"></param>
    /// <param name="vec3Sample"></param>
    /// <param name="param"></param>
    /// <returns></returns>
    // public delegate BakingResult<T> BakeFunction<T>(BakeObject _objToBake, ref List<BakeObject> bakingObjList, ref List<BakeObject> extraObjList, List<Vector3> YupHemiSphereSample, object param);

    ///////////////////////////////////////// Baker /////////////////////////////////////////
    public class BakerBase
    {
        protected List<Vector2> _sample2D;
        protected List<Vector3> _sampleHemiSphere;

        protected BakerBase(int sampleCount = (int)BakeQuality.Great)
        {
            SetBakeSampleCount(sampleCount);
        }

        public void SetBakeQuality(BakeQuality _quality)
        {
            SetBakeSampleCount((int)_quality);
        }

        public void SetBakeSampleCount(int sampleCount)
        {
            if (sampleCount <= 0) return;

            if (_sample2D == null)
            {
                _sample2D = new List<Vector2>();
            }
            _sample2D.Clear();

            // TODO: Add other samples generation methods.
            HammersleyPointSet.Generate(sampleCount, ref _sample2D);

            // Generate Unit Vectors in Hemisphere with normal (0,1,0).
            if (_sampleHemiSphere == null)
            {
                _sampleHemiSphere = new List<Vector3>();
            }

            else
            {
                _sampleHemiSphere.Clear();
            }

            for (int c = 0; c < sampleCount; ++c)
            {
                _sampleHemiSphere.Add(HammersleyPointSet.GetUnitHemisphereRay(_sample2D[c]));
            }
        }

    }

    ///////////////////////////////////////// Baking Result /////////////////////////////////////////
    public class BakingResult<T>
    {
        internal BakeObject _bakeObj;
        internal List<T> _value;

        public List<T> Value
        {
            get { return _value; }
        }

        public BakeObject BakeObj
        {
            get { return _bakeObj; }
        }
    }

}

